<template>
  <el-card shadow="never" class="main-container" style="background-color: white;">
    <template #header>
      <div class="card-header">
        <span>用户查询</span>
      </div>
    </template>
    <el-row :gutter="15" style="margin-bottom: 12px;">
      <el-col :span="10">
        <el-input v-model="state.searchValue">
          <template #prepend>
            <el-select placeholder="查询字段" v-model="state.searchField" style="width: 115px">
              <el-option label="姓名" value="fullname" />
              <el-option label="用户名" value="username" />
            </el-select>
          </template>
        </el-input>
      </el-col>
      <el-col :span="14">
        <el-button type="primary" @click="handleSearch">查询</el-button>
        <el-button type="warning" @click="handleReset">重置</el-button>
        <el-button type="success" @click="addUserVisible = true">新增用户</el-button>
      </el-col>
    </el-row>

    <el-table :data="state.tableData" :loading="state.loading" style="width: 100%">
      <template v-for="(col, index) in columns">
        <el-table-column v-if="col.type === 'selection'" type="selection" :width="col.width" :align="col.align" />
        <el-table-column v-else-if="col.type === 'index'" type="index" :label="col.title" :width="col.width"
          :align="col.align" />
        <el-table-column v-else-if="col.type === 'operation'" :label="col.title" :width="col.width" :align="col.align">
          <template #default="{ row }">
            <el-button type="primary" size="small" plain @click="handleEdit(row)">编辑</el-button>
            <el-popconfirm title="确定删除吗?" @confirm="handleDelete(row)">
              <template #reference>
                <el-button type="danger" size="small" plain>删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
        <el-table-column v-else :label="col.title" :width="col.width" :align="col.align">
          <template #default="{ row }">
            <template v-if="col.enumFn">
              {{ col.enumFn(col, row, index) }}
            </template>
            <template v-else>
              {{ $utils.replaceInvalidValue(row[col.field], row[col.field]) }}
            </template>
          </template>
        </el-table-column>
      </template>
    </el-table>

    <el-pagination v-model:current-page="state.current" v-model:page-size="state.pageSize"
      style="margin: 15px 0 0;justify-content: center;" :total="state.total" :layout="state.layout"
      @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  </el-card>

  <el-dialog title="添加用户" width="650" v-model="addUserVisible" @close="addUserVisible = false">
    <AddUser :status="addUserVisible" @emit-add-user="emitAddUserHandler" />
  </el-dialog>

  <el-dialog title="编辑用户信息" width="650" v-model="editUserVisible" @close="editUserVisible = false">
    <UpdateUserForm :status="editUserVisible" :form-data="state.editRowData"
      @emit-change-user="emitUpdateUserHandler" />
  </el-dialog>
</template>

<script setup>
import AddUser from './AddUser.vue';
import UpdateUserForm from './UpdateUserForm.vue';
import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
import { useStore } from 'vuex';
import { ElMessage } from 'element-plus';

const store = useStore();
const { proxy: { $axios, $utils } } = getCurrentInstance();

const addUserVisible = ref(false);
const editUserVisible = ref(false);
const state = reactive({
  searchValue: '',
  searchField: '',
  loading: false,
  tableData: [],
  current: 1,
  pageSize: 10,
  total: 50,
  layout: 'prev, pager, next, jumper, total',
  editRowData: {}
});

const {
  handleEdit,
  handleDelete,
} = useOperations();

const {
  columns,
  fetchAllUsers,
  handleCurrentChange,
  handleSizeChange,
  handleSearch,
  handleReset,
} = useUsers();

onMounted(() => {
  fetchAllUsers();
});

function emitAddUserHandler({ status, refresh }) {
  addUserVisible.value = status;
  fetchAllUsers(1, refresh);
}
function emitUpdateUserHandler({ status, refresh }) {
  editUserVisible.value = status;
  fetchAllUsers(1, refresh);
}

function useUsers() {
  const columns = [
    { type: 'selection', align: 'center', width: 60 },
    { title: '序号', type: 'index', align: 'center', width: 60 },
    { title: '用户名', field: 'username', colType: '', align: 'center' },
    { title: '姓名', field: 'fullname', colType: '', align: 'center' },
    {
      title: '性别',
      field: 'gender',
      colType: '',
      align: 'center',
      enumKey: 'gender',
      enumFn: getEnumLabel
    },
    { title: '年龄', field: 'age', colType: '', align: 'center' },
    {
      title: '角色',
      field: 'role',
      colType: '',
      enumKey: 'role',
      align: 'center',
      enumFn: (col, row) => {
        const value = parseInt(row[col.field]);
        const enumDef = store.getters['enums/getEnums'](col.enumKey) || {};
        const members = enumDef.getAllMembers() || [];
        const roleLabel = members
          .filter(role => (value & role.value) === role.value)
          .map(role => role.label);

        return roleLabel.join();
      }
    },
    {
      title: '状态',
      field: 'active',
      colType: '',
      align: 'center',
      enumKey: 'user_status',
      enumFn: getEnumLabel
    },
    // { title: '头像', field: 'avatar', colType: '', align: 'center' },
    {
      title: '操作',
      type: 'operation',
      align: 'center',
      width: 150
    },
  ];

  async function fetchAllUsers(page = 1, refresh = true) {
    const path = '/api/user/list';
    const isRefresh = $utils.isValidValue(false) && refresh;
    const { current, pageSize, searchField, searchValue } = state;
    const params = {
      current: page || current,
      pageSize,
      searchField,
      searchValue
    };

    state.loading = true;
    try {
      const { code,
        data: { data, current, pageSize, total },
        message
      } = await $axios.get(path, params);

      if (code === 200) {
        if (isRefresh) {
          ElMessage.success(message);
        }

        state.loading = false;
        state.tableData = escapeDataEnums(data) || [];
        state.current = current;
        state.pageSize = pageSize;
        state.total = total;
      }
    } catch (err) {
      console.error('获取用户列表失败:', err);
    } finally {
      state.loading = false;
    }
  }

  function escapeDataEnums(data = [], suffix = 'Label', cols = columns) {
    const fields = ['gender', 'active'];
    return data.map(row => {
      cols.forEach(col => {
        const condition = fields.includes(col.field) && Reflect.has(col, 'enumKey');

        if (condition) {
          const value = row[col.field];
          const enumDef = store.getters['enums/getEnums'](col.enumKey) || {};

          row[col.field + suffix] = enumDef.getLabel(value);
        }
      });
      return row;
    });
  }

  function handleCurrentChange(page) {
    fetchAllUsers(page)
  }

  function handleSizeChange() {
    fetchAllUsers()
  }

  function handleSearch() {
    const { searchValue, searchField } = state;
    if (searchValue && !searchField) {
      return ElMessage.warning('请选择查询字段');
    }
    fetchAllUsers();
  }

  function handleReset() {
    state.current = 1;
    state.pageSize = 10;
    state.searchValue = '';
    state.searchField = '';
    fetchAllUsers();
  }

  function getEnumLabel(col, row) {
    const value = row[col.field];
    const enumField = col.field + 'Label';
    const enumValue = row[enumField];
    return $utils.replaceInvalidValue(enumValue, value);
  }

  return {
    columns,
    fetchAllUsers,
    handleCurrentChange,
    handleSizeChange,
    handleSearch,
    handleReset
  };
}

function useOperations() {
  function handleEdit(row) {
    editUserVisible.value = true;
    state.editRowData = row;
  }

  async function handleDelete({ id, username } = {}) {
    const path = `/api/user/delete/${id}`;

    try {
      const { code, message } = await $axios.delete(path);

      if (code === 200) {
        ElMessage.success(`用户:【 ${username}】${message}`);
        fetchAllUsers(1, false);
      }
    } catch (err) {
      console.error('用户删除失败:', err);
    }
  }



  return {
    handleEdit,
    handleDelete,
  };
}
</script>